﻿#define FROM_FILE

using System;
using System.Data;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Security.Cryptography.X509Certificates;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using System.Xml;
using System.Xml.Linq;
using System.Xml.Schema;
using System.Xml.Xsl;
using Microsoft.Office.Core;
using Microsoft.Office.Interop.Word;
using eRechnung.Properties;
#if !DEBUG
using Microsoft.Office.Interop.Outlook;
using Application = Microsoft.Office.Interop.Outlook.Application;
#endif
using Exception = System.Exception;
using Office = Microsoft.Office.Core;
using ebDoc = eRechnung.Globals;
using eRechnung.ExtensionMethods;

namespace eRechnung
{
    public class InvoiceXML
    {
        #region RequireDBCopy enum

        public enum RequireDBCopy
        {
            False,
            True
        };

        #endregion

        #region SaveMethodeTypes enum

        public enum SaveMethodeTypes
        {
            SaveAsUnsignedInvoice = 0, // speichert die Rechnung als unsignierte ebInterface REhcnung
            SaveAsTemplate, // speichert die REchnung als Vorlage
            MailSignedInvoice,
            MailUnsignedInvoice // 
        }

        #endregion

        #region TemplateTypes enum

        public enum TemplateTypes
        {
            Empty,
            FromFile
        };

        #endregion

        public enum SignTypes
        {
            NoSignature = 0,
            Handy,
            AskAlways
        }
        public const string ebInterface_Version = "/4p0/";
        public const string ebInterface_Version3p02 = "/3p02/";
        public const string ebInterface_Version3p0 = @"/3p0/";

        public const string Prefix = "xmlns:eb='http://www.ebinterface.at/schema" + ebInterface_Version + @"'";
        public const string PrefixURLeb = @"http://www.ebinterface.at/schema" + ebInterface_Version + @"";
        public const string PrefixURLsig = @"http://www.w3.org/2000/09/xmldsig#";

        public const string PrefixSchemaLocation = @"http://www.ebinterface.at/schema" + ebInterface_Version +
                                                   @" http://www.ebinterface.at/schema" + ebInterface_Version +
                                                   @"Invoice.xsd";

        public const string ebInterface_Stylesheet =
            "type=\"text/xsl\" href=\"http://www.ebinterface.at/download/invoiceexample"
            + ebInterface_Version + "invoice.xslt\"";

        public const string xPathListLine = "eb:Invoice/eb:Details/eb:ItemList/eb:ListLineItem";
        public const string xPathItemList = "eb:Invoice/eb:Details/eb:ItemList";
        public const string xPathDetailsHeader = "eb:Invoice/eb:Details/eb:HeaderDescription";
        public const string xPathDetailsFooter = "eb:Invoice/eb:Details/eb:FooterDescription";
        public const string xPathPos = "eb:PositionNumber";
        public const string xPathDesc = "eb:Description";
        public const string xPathArtikelNr = "eb:ArticleNumber";
        public const string xPathArtikelNr3p0x = "eb:BillersArticleNumber";
        public const string xPathArtikelNrType = "eb:ArticleNumberType=\"BillersArticleNumber\"";
        public const string xPathUnit = "eb:Quantity/@eb:Unit";
        public const string xPathQuantity = "eb:Quantity";
        public const string xPathUnitPrice = "eb:UnitPrice";

        public const string xPathReductionRate3p02 = "eb:ReductionRate";
        //  "eb:ReductionAndSurchargeListLineItemDetails/eb:Reduction/eb:Percentage

        public const string xPathReductionRate =
            "eb:ReductionAndSurchargeListLineItemDetails/eb:ReductionListLineItem/eb:Percentage"; //  "

#if ebInterface4Bund
        public const string xPathInvOrderRef = "eb:InvoiceRecipientsOrderReference/eb:OrderPositionNumber";
#endif

        public const string xPathAmount = "eb:LineItemAmount";
        public const string xPathTaxRate = "eb:TaxRate";
        public const string xPathTaxCode = "eb:TaxRate/@eb:TaxCode";

        public const string xAttrCountryCode = "CountryCode";

        public const string xPathInvoice = "eb:Invoice";
        public const string xPathBillerName = "//eb:Biller/eb:Address/eb:Name";
        public const string xPathBillerStreet = "//eb:Biller/eb:Address/eb:Street";
        public const string xPathBillerTown = "//eb:Biller/eb:Address/eb:Town";
        public const string xPathBillerZip = "//eb:Biller/eb:Address/eb:ZIP";
        public const string xPathBillerCountry = "//eb:Biller/eb:Address/eb:Country";
        public const string xPathBillerContact = "//eb:Biller/eb:Address/eb:Contact";
        public const string xPathBillerPhone = "//eb:Biller/eb:Address/eb:Phone";
        public const string xPathBillerEmail = "//eb:Biller/eb:Address/eb:Email";
        public const string xPathBillerVATID = "//eb:Biller/eb:VATIdentificationNumber";
#if ebInterface4Bund
        public const string xPathBillerGlnId = "//eb:Biller/eb:Address/eb:AddressIdentifier";
        public const string xPathBillerInvRecBillersID = "//eb:Biller/eb:InvoiceRecipientsBillerID";
#endif

        public const string xPathInvRecName = "//eb:InvoiceRecipient/eb:Address/eb:Name";
        public const string xPathInvRecSalute = "//eb:InvoiceRecipient/eb:Address/eb:Salutation";
        public const string xPathInvRecStreet = "//eb:InvoiceRecipient/eb:Address/eb:Street";
        public const string xPathInvRecTown = "//eb:InvoiceRecipient/eb:Address/eb:Town";
        public const string xPathInvRecZip = "//eb:InvoiceRecipient/eb:Address/eb:ZIP";
        public const string xPathInvRecCountry = "//eb:InvoiceRecipient/eb:Address/eb:Country";
        public const string xPathInvRecPhone = "//eb:InvoiceRecipient/eb:Address/eb:Phone";
        public const string xPathInvRecContact = "//eb:InvoiceRecipient/eb:Address/eb:Contact";
        public const string xPathInvRecEmail = "//eb:InvoiceRecipient/eb:Address/eb:Email";
        public const string xPathInvRecVATID = "//eb:InvoiceRecipient/eb:VATIdentificationNumber";
        public const string xPathInvAcctArea = "//eb:InvoiceRecipient/eb:AccountingArea";
        public const string xPathInvSubOrgID = "//eb:InvoiceRecipient/eb:SubOrganizationID";
        public const string xPathInvRecBillerID = "//eb:InvoiceRecipient/eb:BillersInvoiceRecipientID";
#if ebInterface4Bund
        public const string xPathInvRecGlnId = "//eb:InvoiceRecipient/eb:Address/eb:AddressIdentifier";
#endif

        public const string xPathDocumentType = "//eb:Invoice/@eb:DocumentType";
        public const string xPathDocumentTitle = "//eb:Invoice/@eb:DocumentTitle";
        public const string xPathCurrency = "//eb:Invoice/@eb:InvoiceCurrency";
        public const string xAttrGeneratingSystem = "eb:GeneratingSystem";

        public const string xAttrXmlnseb = "xmlns:eb";
        // public const string xAttrGeneratingSystem = "eb:GeneratingSystem";
        public const string xAttrSchemaLocation = "xsi:schemaLocation";

        public const string xPathInvNumber = "//eb:InvoiceNumber";
        public const string xPathInvDate = "//eb:InvoiceDate";
        public const string xPathDeliveryDate = "//eb:Delivery/eb:Date";
        public const string xPathOrderRefID = "//eb:OrderReference/eb:OrderID";
        public const string xPathOrderRefDate = "//eb:OrderReference/eb:ReferenceDate";
        public const string xPathOrderReference = "//eb:OrderReference";

        public const string xPathPaymtDuedate = "//eb:PaymentConditions/eb:DueDate";
        public const string xPathBankName = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankName";
        // public const string xPathBankBLZ = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankCode";
        public const string xPathBankBIC = "eb:Invoice/eb:PaymentMethod/eb:BeneficiaryAccount/eb:BIC";

        public const string xPathBankLand =
            "eb:Invoice/eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankCode/@eb:BankCodeType";

        // public const string xPathBankAcctNr = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankAccountNr";
        public const string xPathBankAcctOwner = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:BankAccountOwner";
        public const string xPathBankIBAN = "//eb:PaymentMethod/eb:BeneficiaryAccount/eb:IBAN";
        public const string xPathPaymtMethode = "//eb:PaymentMethod";
        public const string xPathPaymtReferenz = "//eb:PaymentMethod/eb:PaymentReference";


        public const string xPathSignature = "//dsig:Signature";

        public const string xPathCertificate =
            "/eb:Invoice/dsig:Signature/dsig:KeyInfo/dsig:X509Data/dsig:X509Certificate";

        public const string xPathDiscntPmntCond = "eb:Invoice/eb:PaymentConditions";
        public const string xPathDiscntLine = "eb:Invoice/eb:PaymentConditions/eb:Discount";
        public const string xPathDiscntProz = "eb:Percentage";
        public const string xPathDiscntDate = "eb:PaymentDate";
        public const string xPathDiscntDueDate = "eb:DueDate";
        public const string DueDateXML = "<eb:DueDate>{0}</eb:DueDate>";

        public const string DiscItemXML = "<eb:Discount>" +
                                          "<eb:PaymentDate>{0}</eb:PaymentDate>" +
                                          "<eb:Percentage>{1}</eb:Percentage>" +
                                          "<eb:Amount>{2}</eb:Amount>" +
                                          "</eb:Discount>";


        public const string xPathTaxVATList = "//eb:Tax/eb:VAT";

        public const string xPathTotGrossAmount = "//eb:TotalGrossAmount";

        private const string VatItemXML = "<eb:Item>" +
                                          "<eb:TaxedAmount>{0}</eb:TaxedAmount>" +
                                          "<eb:TaxRate>{1}</eb:TaxRate>" +
                                          "<eb:Amount>{2}</eb:Amount>" +
                                          "</eb:Item>";

        private const string VAT_TaxExemption = "<eb:TaxExemption>{0}</eb:TaxExemption>";

        /*
		 * Templates für ListLineItem
		 * */
        private const string Rabatt_true = "true";
        private const string Rabatt_false = "false";

        private const string DetailItemXml = "<eb:ListLineItem>" +
                                             "<eb:PositionNumber>{0}</eb:PositionNumber>" +
                                             "<eb:Description>{1}</eb:Description>" +
                                             "<eb:ArticleNumber>{2}</eb:ArticleNumber>" +
                                             "<eb:Quantity eb:Unit='{3}'>{4}</eb:Quantity>" +
                                             "<eb:UnitPrice>{5}</eb:UnitPrice>" +
                                             "<eb:TaxRate{10}>{6}</eb:TaxRate>" +
                                             "<eb:DiscountFlag>{7}</eb:DiscountFlag>" +
                                             "{8}" +
                                             "<eb:LineItemAmount>{9}</eb:LineItemAmount>" +
                                             "</eb:ListLineItem>";

        private const string ReductionAndSurchargeXML = "<eb:ReductionAndSurchargeListLineItemDetails>" +
                                                        "<eb:ReductionListLineItem>" +
                                                        "<eb:BaseAmount>{1}</eb:BaseAmount>" +
                                                        "<eb:Percentage>{0}</eb:Percentage>" +
                                                        "</eb:ReductionListLineItem>" +
                                                        "</eb:ReductionAndSurchargeListLineItemDetails>";
#if ebInterface4Bund
        private const string InvoiceRecipientsOrderReferenceXML = "<eb:InvoiceRecipientsOrderReference>" +
                                                                  "<eb:OrderID>{0}</eb:OrderID>" +
                                                                  "<eb:OrderPositionNumber>{1}</eb:OrderPositionNumber>" +
                                                                  "</eb:InvoiceRecipientsOrderReference>";

        private const string DocumentTitleVorlage = "XML Vorlage für ebInterface 4.0 Bund";
        private const string DocumentTitleVorlage3P0 = "XML Vorlage für ebInterface 3.0 Bund";

        // ToDo Need a different Salt!
        private const string DocTitleMsg =
            "Die XML Vorlage wurde nicht mit ebInterface 4.0 Word Vorlage für den Bund erstellt. Die Vorlage wurde nicht geladen";

#else
        private const string DocumentTitleVorlage = "XML Vorlage für ebInterface 4.0 Word";
        private const string DocumentTitleVorlage3P0 = "XML Vorlage für ebInterface 3.0 Word";
        private const string DocTitleMsg =
            "Die XML Vorlage wurde nicht mit ebInterface 3.0, 3.02 oder 4.0 Word Vorlage erstellt. Die Vorlage wurde nicht geladen";
        
#endif

        private const string _DocumentTitleFInal = "";

        private readonly string[] VAT_Country_Code = {
                                                         "AT",
                                                         "BE",
                                                         "BG",
                                                         "CY",
                                                         "CZ",
                                                         "DE",
                                                         "DK",
                                                         "EE",
                                                         "GR",
                                                         "ES",
                                                         "FI",
                                                         "FR",
                                                         "GB",
                                                         "HU",
                                                         "IE",
                                                         "IT",
                                                         "LT",
                                                         "LU",
                                                         "LV",
                                                         "MT",
                                                         "NL"
                                                     };

        private string DocumentTitle = "";

        public SaveMethodeTypes SaveMethodeType { get; set; }

        public ZustellSetting SelectedZustelldienst;

        private const string CCTag_NichtLeer = "nicht leer";
        //private const string CCTag_BundNichtLeer = "Bund nicht leer";
        private const string CCTag_VAT = "vat";
        private const string CCTag_Num = "numerisch";
        //private const string CCTag_BuKreis = "Buchungskreis";
        //private const string CCTag_OrderID = "OrderRef";
        private const string InvoiceXSDFile = "eRechnung.Invoice4p0NoSigNoExt.xsd";
        private const string xmlDsigXSDFile = "eRechnung.W3C-XMLDSig.xsd";
        public const string ebInterfaceLeer = "eRechnung.ebInterface_Leer.xml";
        public const string XMLSignRequest = "eRechnung.XMLSignRequest.xml";
        private readonly object missing = Type.Missing;
        //public string InvBankCountry;
        //public string InvBankCountryCode;
        public string InvBillerCountry;
        public string InvBillerCountryCode;
        public string InvCurrency;
        public DsInvoice InvDetails;
        public string InvDocTitle;
        public string InvDocType;
        public string InvRecipientCountry;
        public string InvRecipientCountryCode;
        public bool IsXmlValid
        {
            get { return _isXmlValid; }
        }

        private bool _isXmlValid;
        private bool bSaveLocal;
        private bool bSendEtresor;
        private bool bSendMail;
        private bool bSendZustelldienst;
        private string strEMailAddress;
        private string strEtresorAddress;
        private string strLocalFilename;

        public InvoiceXML()
        {
            InvDetails = new DsInvoice();
            _isXmlValid = false;
        }

        public string LocalFileName
        {
            get { return strLocalFilename; }
        }


        public CustomXMLPart AddCustomXmlPart(string xmlData)
        {
            // System.Diagnostics.Debugger.Break();
            // Office.CustomXMLPart InvoiceXMLPart;


            try
            {
                if (xmlData != null)
                {
                    if (Globals.ThisDocument.InvoiceXMLPartID == null)
                    {
                        Globals.ThisDocument.InvoiceXMLPart = Globals.ThisDocument.CustomXMLParts.Add(xmlData, missing);
                        Globals.ThisDocument.InvoiceXMLPartID = Globals.ThisDocument.InvoiceXMLPart.Id;
                        Globals.ThisDocument.SetCustomXMLID(Globals.ThisDocument.InvoiceXMLPartID);
                    }
                    else
                    {
                        Globals.ThisDocument.InvoiceXMLPart =
                            Globals.ThisDocument.CustomXMLParts.SelectByID(Globals.ThisDocument.InvoiceXMLPartID);
                    }
                    Globals.ThisDocument.UnprotectDoc("AddCustomXmlPart");
                    Globals.ThisDocument.InvoiceXMLPart.NamespaceManager.AddNamespace("eb", PrefixURLeb);
                    Globals.ThisDocument.ProtectDoc("AddCustomXmlPart");

                    return (Globals.ThisDocument.InvoiceXMLPart);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message + "\r\n" + ex.Source + "\r\n" + ex.StackTrace);
                //throw;
            }
            return (null);
        }

        /// <summary>
        /// Ruft die Methode SaveXMLPrivate zum speichern des CustomXMLPart als XML Datei auf.
        /// <see cref="SaveXmlPrivate"/>
        /// </summary>
        /// <param name="SaveTyp">Gibt an ob das XML als Vorlage oder ebInterface Rechnung gespeichert wird</param>
        public void SaveXml(SaveMethodeTypes SaveTyp)
        {
            // InvBankCountry = Globals.ThisDocument.CC_BankCountry.Text;
            // InvBankCountryCode = Globals.ThisDocument.XlateTables.FindShortcut(Globals.ThisDocument.CC_BankCountry.Text);
            InvBillerCountry = Globals.ThisDocument.CC_BillerCountry.Text;
            InvBillerCountryCode = Globals.ThisDocument.XlateTables.FindShortcut(Globals.ThisDocument.CC_BillerCountry.Text);
            InvRecipientCountry = Globals.ThisDocument.CC_RecipientCountry.Text;
            InvRecipientCountryCode =
                Globals.ThisDocument.XlateTables.FindShortcut(Globals.ThisDocument.CC_RecipientCountry.Text);
            InvCurrency = Globals.ThisDocument.CC_Currency.Text;
            InvDocType = Globals.ThisDocument.XlateTables.FindDocTypeEnglish(Globals.ThisDocument.CC_InvoiceType.Text);
            // translation needed
            InvDocTitle = Globals.ThisDocument.CC_DocumentTitle.Text;
            SaveMethodeType = SaveTyp;
            SaveXmlPrivate(Globals.ThisDocument.InvoiceXMLPart);
        }


        /// <summary>
        /// 
        /// Speicher den angegebene CustomXMLPart als XML Datei
        /// </summary>
        /// <param name="XMLPart">Der zu speichernde CustomXMLPart</param>
        private void SaveXmlPrivate(CustomXMLPart XMLPart)
        {

            #region verify Contentcontrols
            _isXmlValid = false;
            if (SaveMethodeType != SaveMethodeTypes.SaveAsTemplate)
            {

                string ccVerify = VerifyAllCC();
                if (ccVerify != "")
                {
                    Globals.ThisDocument.SetFehlerText(ccVerify);
                    ShowDataError();
                    return;
                }
                _isXmlValid = true;
            }
            #endregion
            #region XML Document bauen
            Document wDoc = Globals.ThisDocument.Application.ActiveDocument;
            string retVal = String.Empty;
            foreach (ContentControl wCC in wDoc.ContentControls)
            {
                string xPathInXml = wCC.XMLMapping.XPath;
                if (xPathInXml != null)
                {
                    // Code do mke shure that changed fields are put inside CustomXML
                    CustomXMLNode xNode = Globals.ThisDocument.InvoiceXMLPart.SelectSingleNode(xPathInXml);
                    Debug.WriteLine("Update: " + wCC.PlaceholderText.Value + "/" + wCC.Tag + "<" + wCC.Range.Text + "> " +
                                    xPathInXml + "=<" + xNode.Text + ">");
                    if ((wCC.ShowingPlaceholderText != true) && (xNode.Text != wCC.Range.Text))
                    {
                        Globals.ThisDocument.UnprotectDoc("SaveXML");
                        xNode.Text = wCC.Range.Text;
                        Globals.ThisDocument.ProtectDoc("SaveXML");
                    }
                }
            }

            var xdoc = new XmlDocument();
            xdoc.PreserveWhitespace = true;
            var xNMgr = new XmlNamespaceManager(xdoc.NameTable);
            xNMgr.AddNamespace("eb", PrefixURLeb);
            xNMgr.AddNamespace("dsig", PrefixURLsig);

            // Daten aufbauen
            try
            {
                string ItemXML = String.Empty;
                xdoc.LoadXml(XMLPart.XML);
                xdoc.CreateXmlDeclaration("1.0", "utf-8", String.Empty);

                XmlNode xn = xdoc.SelectSingleNode(xPathBillerCountry, xNMgr);
                // xn.InnerText = InvBillerCountryCode;
                // xn.Attributes[xAttrCountryCode].Value = InvBillerCountryCode;
                xn = SetCountry(xn, InvBillerCountry, InvBillerCountryCode);
                xn = xdoc.SelectSingleNode(xPathSignature, xNMgr);
                if (xn != null)
                {
                    Debug.WriteLine("gelöscht: " + xn.InnerXml);
                    xn.ParentNode.RemoveChild(xn);
                }

                //xn = xdoc.SelectSingleNode(xPathBankBLZ, xNMgr);
                //if (xn != null)
                //{
                //    if (xn.InnerText != "")
                //    {
                //        xdoc.SelectSingleNode(xPathBankLand, xNMgr).InnerText = InvBankCountryCode;
                //    }
                //    else
                //    {
                //        if (SaveMethodeType != SaveMethodeTypes.SaveAsTemplate)
                //        {
                //            xn.ParentNode.RemoveChild(xn);
                //        }
                //    }
                //}

                // xdoc.SelectSingleNode(xPathInvRecCountry, xNMgr).InnerText = InvRecipientCountry;
                xn = xdoc.SelectSingleNode(xPathInvRecCountry, xNMgr);
                xn = SetCountry(xn, InvRecipientCountry, InvRecipientCountryCode);

                xdoc.SelectSingleNode(xPathCurrency, xNMgr).InnerText = InvCurrency;
                xdoc.SelectSingleNode(xPathDocumentType, xNMgr).InnerText = InvDocType;
                xdoc.SelectSingleNode(xPathDocumentTitle, xNMgr).InnerText = InvDocTitle;
                string[] tempSVN = Globals.ThisDocument.GetSVNInfo().Split(';');
                if (SaveMethodeType != SaveMethodeTypes.SaveAsTemplate)
                {
                    DocumentTitle = Globals.ThisDocument.GetAsmTitle();
                }
                else
                {
                    DocumentTitle = DocumentTitleVorlage;
                }

                xdoc.DocumentElement.Attributes[xAttrGeneratingSystem].InnerText = DocumentTitle + " " + tempSVN[0];
                ;
                // xdoc.SelectSingleNode(xAttrGeneratingSystem, xNMgr).InnerText = DocumentTitle+" "+tempSVN[0];
                xdoc.SelectSingleNode(xPathInvDate, xNMgr).InnerText =
                    FormatDateVonXML(xdoc.SelectSingleNode(xPathInvDate, xNMgr).InnerText);
                xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText =
                    FormatDateVonXML(xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText);
                xdoc.SelectSingleNode(xPathOrderRefDate, xNMgr).InnerText =
                    FormatDateVonXML(xdoc.SelectSingleNode(xPathOrderRefDate, xNMgr).InnerText);
                xdoc.SelectSingleNode(xPathTotGrossAmount, xNMgr).InnerText =
                    FormatDecimal(Globals.ThisDocument.BetragInklMwSt);

#if ebInterface4Bund
                string orderId4Bund = GetItem(xdoc, xNMgr, xPathOrderRefID);
                ItemXML = Details2XML(orderId4Bund);
#else  
		        ItemXML = Details2XML();
#endif
                XmlNode ItemNode = xdoc.SelectSingleNode(xPathItemList, xNMgr);
                ItemNode.InnerXml = ItemXML;

                ItemXML = MwSt2XML();
                ItemNode = xdoc.SelectSingleNode(xPathTaxVATList, xNMgr);
                ItemNode.InnerXml = ItemXML;

                ItemNode = xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr);
                ItemXML = Skonto2XML();
                ItemXML = String.Format(DueDateXML, ItemNode.InnerXml) + ItemXML;
                ItemNode = xdoc.SelectSingleNode(xPathDiscntPmntCond, xNMgr);
                ItemNode.InnerXml = ItemXML;


            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei XML Verarbeitung.\r\n" + ex.Message);
                return;
            }
            #endregion

            #region XML validieren
            if (SaveMethodeType != SaveMethodeTypes.SaveAsTemplate) // wenn als Vorlage zu speichern, keine Validierung
            {
                xdoc = RemoveEmptyNodes(xdoc);
                string Tmp2Filename = Path.GetTempFileName(); // Temporaeren Dateinamen wählen

                xdoc.Save(Tmp2Filename);

                bool isValid = IsEbInterfaceXMLValid(xdoc, Tmp2Filename, false);
                if (isValid == false)
                {
                    ShowDataError();
                    return;
                }
            }
            #endregion

            switch (SaveMethodeType)
            {
                case SaveMethodeTypes.SaveAsTemplate:
                case SaveMethodeTypes.SaveAsUnsignedInvoice:
                    strLocalFilename = SaveAsUnsignedXml(xNMgr, xdoc);
                    return;
                    break;
                case SaveMethodeTypes.MailUnsignedInvoice:
                case SaveMethodeTypes.MailSignedInvoice:
                    strLocalFilename = SignXmlAndSaveInvoice(xdoc);
                    break;
                default:
                    throw new NotImplementedException();
            }

        }

        private XmlDocument RemoveEmptyNodes(XmlDocument source)
        {
            //Xsl to strip stylesheet    
            string strippingStylesheet = "<?xml version=\"1.0\"" +
                " encoding=\"UTF-8\" ?>" +
                "<xsl:stylesheet version=\"1.0\"" +
                " xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" +
                "<xsl:output omit-xml-declaration=\"no\" indent=\"no\"/>" +
                "<xsl:strip-space elements=\"*\" />" +
                "<xsl:template match=\"*[not(node()) and not(./@*)]\"/>" +
                "<xsl:template match=\"@* | node()\">" +
                "<xsl:copy>" +
                "<xsl:apply-templates select=\"@* | node()\"/>" +
                "</xsl:copy>" +
                "</xsl:template>" +
                "</xsl:stylesheet>";
            const string strip2 = "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">" +
                "<xsl:template match=\"@*|node()\">" +
                "<xsl:if test=\". != ''\">" +
                "<xsl:copy>" +
                "<xsl:apply-templates select=\"@*|node()\"/>" +
                "</xsl:copy>" +
                "</xsl:if>" + "</xsl:template>" + "</xsl:stylesheet>";
            ////Set up empty node stripper    
            //XmlDocument stripper = new XmlDocument();    
            //stripper.LoadXml(strip2);    
            ////Compile here    
            //XslCompiledTransform emptyNodeRemover = new XslCompiledTransform();    
            //emptyNodeRemover.Load(stripper);     
            ////Port output to string     
            //StringWriter output = new StringWriter();    
            //emptyNodeRemover.Transform(new XmlNodeReader(source), null, output);    
            //output.Flush();    
            ////Reload source with emptied nodes    
            //source.LoadXml(output.ToString());    
            //output.Close();    
            //output.Dispose();

            var doc = XDocument.Parse(source.InnerXml);
            doc.Descendants()
                .Where(e => e.IsEmpty || String.IsNullOrWhiteSpace(e.Value))
                .Remove();

            var outDoc = doc.ToXmlDocument();

            return outDoc;
        }


        private string SaveAsUnsignedXml(XmlNamespaceManager xNMgr, XmlDocument xdoc)
        {
            String strRenr = GetItem(xdoc, xNMgr, xPathInvNumber);
            String strReDatum = GetItem(xdoc, xNMgr, xPathInvDate);

            string strLocalFn = MakeFileName(strRenr, strReDatum);

            var sDlg = new SaveFileDialog();

            sDlg.InitialDirectory = SaveMethodeType == SaveMethodeTypes.SaveAsTemplate ? Settings.Default.setTemplatePath : Settings.Default.setLocalPath;

            sDlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
            sDlg.FilterIndex = 1;
            sDlg.RestoreDirectory = true;
            sDlg.FileName = strLocalFn;
            if (sDlg.ShowDialog() == DialogResult.OK)
            {
                if (File.Exists(sDlg.FileName))
                {
                    File.Delete(sDlg.FileName);
                }
                strLocalFn = sDlg.FileName;
            }
            else
            {
                return "";
            }
            try
            {
                WriteXML(xdoc, strLocalFn);

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Save As XML");
            }
            return strLocalFn;
        }

        private string SignXmlAndSaveInvoice(XmlDocument xdoc)
        {
            XmlNamespaceManager xNMgr;
            XmlDocument signedXML;
            var RR = new ebInterfaceXMLSign();
#if TEST_A_TRUST
                RR.Target = ebInterfaceXMLSign.RequestTarget.TestSystem;
#else
            RR.Target = ebInterfaceXMLSign.RequestTarget.ProductionSystem;
#endif
            signedXML = new XmlDocument();
            xNMgr = new XmlNamespaceManager(signedXML.NameTable);
            xNMgr.AddNamespace("eb", PrefixURLeb);
            xNMgr.AddNamespace("dsig", PrefixURLsig);

            signedXML.PreserveWhitespace = true;
            try
            {
#if DEBUG && SAVE_HTML
					RR.savehtml(xdoc.InnerXml, "xdocBeforeSign.xml");
#endif
                if (SaveMethodeType == SaveMethodeTypes.MailSignedInvoice)
                {
                    signedXML = RR.SignXML(xdoc);
                    if (signedXML == null)
                    {
                        return "";
                    }
#if DEBUG && SAVE_HTML
				   RR.savehtml(signedXML.OuterXml, "signedAfterReturn.xml");
#endif
                    XmlDeclaration xdeclare;
                    xdeclare = signedXML.CreateXmlDeclaration("1.0", "utf-8", String.Empty);
                    XmlElement root = signedXML.DocumentElement;
                    signedXML.InsertBefore(xdeclare, root);

                    XmlProcessingInstruction xproc;
                    xproc = signedXML.CreateProcessingInstruction("xml-stylesheet", ebInterface_Stylesheet);
                    //xdoc.AppendChild(xproc);
                    signedXML.InsertBefore(xproc, root);
                }
                else
                {
                    signedXML = BeautifyXml(xdoc);
                }

                string sendFilename = "";

                DialogResult dResult = ShowSignResult(signedXML, xNMgr, out sendFilename);
                if (dResult != DialogResult.OK)
                {
                    return "";
                }

                if (bSaveLocal)
                {
                    // signedXML.Save(strLocalFilename);
                    XmlWriter xWrt = XmlWriter.Create(sendFilename);
                    signedXML.WriteContentTo(xWrt);
                    xWrt.Close();
                    MessageBox.Show("ebInterface Rechnung gespeichert unter " + sendFilename);
                    // sendFilename = strLocalFilename;
                }
                else
                {

                    //sendFilename = Path.GetTempPath(); // Path.GetTempFileName();
                    sendFilename =
                    Path.Combine(Path.GetTempPath(),
                                 MakeFileName(GetItem(signedXML, xNMgr, xPathInvNumber), GetItem(signedXML, xNMgr, xPathInvDate)));
                    File.Delete(sendFilename);
                    XmlWriter xWrt = XmlWriter.Create(sendFilename);
                    signedXML.WriteContentTo(xWrt);
                    xWrt.Close();

                }
#if NO_ETRESOR
				   bSendEtresor = false;
#endif
                SendInvoice(sendFilename, xNMgr, signedXML);
                return sendFilename;
            }
            catch (Exception ex)
            {
                string msg = ex.Message;
#if DEBUG  && SAVE_HTML
					msg = msg + "\r\n" + ex.StackTrace;
					Debug.WriteLine(msg);
#endif
                MessageBox.Show(ex.Message, "Signieren und Versenden");
                return "";
            }
        }

        public static XmlDocument BeautifyXml(XmlDocument xdoc)
        {
            //MemoryStream aus dem Xml-Dokument erzeugen
            XmlTextWriter xmlWriter;

            StringWriter textWriter;

            // Format the Xml document with indentation and save it to a string.

            textWriter = new StringWriter();
            xmlWriter = new XmlTextWriter(textWriter);
            xmlWriter.Formatting = Formatting.Indented;
            xdoc.Save(xmlWriter);
            string xText = textWriter.ToString();
            XmlDocument beautyXML = new XmlDocument();
            beautyXML.PreserveWhitespace = true;
            beautyXML.LoadXml(xText);
#if DEBUG && SAVE_HTML
           savehtml(beautyXML.OuterXml, "BeautyXML.xml");
#endif
            return beautyXML;
        }

        private void SendInvoice(string sendFilename, XmlNamespaceManager xNMgr, XmlDocument signedXML)
        {
            if (bSendEtresor || bSendMail)
            {
                string subj = Settings.Default.setBetreff;
                if (subj == "")
                {
                    subj = Settings.Default.defaultMailSubject;
                }
                subj = ReplaceToken(subj, signedXML, xNMgr);

                string MText = Settings.Default.setMailText;
                if (MText == "")
                {
                    MText = Settings.Default.defaultMailBody;
                }
                MText = ReplaceToken(MText, signedXML, xNMgr);
#if DEBUG  && SAVE_HTML
					   MessageBox.Show("Mail senden an: " + strEMailAddress + "\r\n" +
						   "e-Tresor: " + strEtresorAddress + "\r\n" +
						   subj + "\r\n" + MText);
#endif
                strEtresorAddress = "";
#if !NO_ETRESOR
                if (bSendEtresor == false)
                {
                    strEtresorAddress = "";
                }
#endif
                if (bSendMail == false)
                {
                    strEMailAddress = "";
                }
                SendMail(strEMailAddress, strEtresorAddress, subj, MText, sendFilename);
            }

            if (bSendZustelldienst)
            {
                if (SelectedZustelldienst == null)
                {
                    SelectedZustelldienst = Settings.Default.setZustellungDefault;

                    if (SelectedZustelldienst == null)
                    {
                        MessageBox.Show("Bevorzugter Zustelldienst nicht konfiguriert.", "Versenden", MessageBoxButtons.OK,
                                        MessageBoxIcon.Stop);
                        return;
                    }
                }
                string parm = SelectedZustelldienst.Parm.Replace("[eRechnung]", "\"" + sendFilename + "\"");
                Process.Start(SelectedZustelldienst.ProgramPath, parm);
                SelectedZustelldienst = null; // Important Cleanup!
            }
        }

        private void ShowDataError()
        {
            MessageBox.Show("Bei der Datenprüfung wurden Fehler gefunden.\r\n" +
                            "Details finden Sie auf Seite 2 dieses Formulars.\r\n",
                            "ebInterface prüfen", MessageBoxButtons.OK, MessageBoxIcon.Error);

            Globals.ThisDocument.Bookmarks["Fehlerliste"].Select();
            return;
        }

        private void WriteXML(XmlDocument xdoc, string filename)
        {
            var xwsetting = new XmlWriterSettings();
            xwsetting.Indent = true;
            xwsetting.NewLineChars = Environment.NewLine;
            XmlWriter myXMLWriter = XmlWriter.Create(filename, xwsetting);
            xdoc.Save(myXMLWriter);
            myXMLWriter.Close();
            myXMLWriter.Flush();
        }

        private string ReplaceToken(string source, XmlDocument xdoc, XmlNamespaceManager xNmgr)
        {
            string[] Tokens = {
                                  "[RECHNUNGSNR]", "[RECHNUNGSDATUM]", "[RECHNUNGSSTELLER]", "[KONTAKT]", "[TELEFON]",
                                  "[EMAIL]"
                              };
            string[] TkxPath = {
                                   xPathInvNumber, xPathInvDate, xPathBillerName, xPathBillerContact, xPathBillerPhone,
                                   xPathBillerEmail
                               };
            string tmpString = source;
            for (int i = 0; i < Tokens.Length; i++)
            {
                XmlNode xn = xdoc.SelectSingleNode(TkxPath[i], xNmgr);
                string replText = "-";
                if (xn != null)
                {
                    replText = xn.InnerText;
                }
                tmpString = tmpString.Replace(Tokens[i], replText);
            }
            return tmpString;
        }

        private DialogResult ShowSignResult(XmlDocument signedDoc, XmlNamespaceManager signedMgr, out string fn)
        {
            string signer = "Nicht signiert";
            string issuer = "Nicht signiert";
            var dlgConfirm = new FrmConfirm();
            dlgConfirm.IsSigned = false;

            string certstr = GetItem(signedDoc, signedMgr,
                                     @"/eb:Invoice/dsig:Signature/dsig:KeyInfo/dsig:X509Data/dsig:X509Certificate");


            if (certstr != "")
            {
                byte[] certbyte = Convert.FromBase64String(certstr);
                var cert = new X509Certificate2(certbyte);
                signer = cert.SubjectName.Name;
                issuer = cert.IssuerName.Name;
                XmlNode ndKeyInfo = signedDoc.SelectSingleNode(@"/eb:Invoice/dsig:Signature/dsig:KeyInfo", signedMgr);
                XmlElement elKeyName = signedDoc.CreateElement("dsig", "KeyName", PrefixURLsig);
                elKeyName.InnerText = signer;
                ndKeyInfo.AppendChild(elKeyName);
                dlgConfirm.IsSigned = true;
            }


            // AnzPos
            XmlNodeList lineItems = signedDoc.SelectNodes(xPathListLine, signedMgr);
            dlgConfirm.strAnzPos = lineItems.Count.ToString("D");
            dlgConfirm.strEMailAddress = GetItem(signedDoc, signedMgr, xPathInvRecEmail);
            if (dlgConfirm.strEMailAddress != "")
            {
                dlgConfirm.bSendMail = true;
            }
            else
            {
                dlgConfirm.bSendMail = false;
            }
            dlgConfirm.strGesBetrag = GetItem(signedDoc, signedMgr, xPathCurrency) + " " +
                                      GetItem(signedDoc, signedMgr, xPathTotGrossAmount);
            dlgConfirm.strReEmpfaenger = GetItem(signedDoc, signedMgr, xPathInvRecName);
            dlgConfirm.strReNr = GetItem(signedDoc, signedMgr, xPathInvNumber);
            dlgConfirm.strReDatum = GetItem(signedDoc, signedMgr, xPathInvDate);
            dlgConfirm.strReSteller = GetItem(signedDoc, signedMgr, xPathBillerName);

            dlgConfirm.strSignator = signer;
            dlgConfirm.strZertIssuer = issuer;

            dlgConfirm.bSendEtresor = Settings.Default.setSendEtresor;
            dlgConfirm.strEtresorAddress = Settings.Default.setEtresorMail;

            dlgConfirm.bSaveLocal = Settings.Default.setSaveLocal;
            string strLocalFn = MakeFileName(dlgConfirm.strReNr, dlgConfirm.strReDatum);

            // ToDo Auf Unsignierten Versand prüfen und anderes Verzeichnis vorschlagen
            switch (SaveMethodeType)
            {
                case SaveMethodeTypes.MailSignedInvoice:
                    dlgConfirm.strLocalFilename = Path.Combine(Settings.Default.setLocalPathSigned, strLocalFn);
                    break;
                case SaveMethodeTypes.MailUnsignedInvoice:
                    dlgConfirm.strLocalFilename = Path.Combine(Settings.Default.setLocalPath, strLocalFn);
                    dlgConfirm.strSignText = "Die Rechnung wurde erfolgreich gemäß ebInterface Standard geprüft.";
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }

            ZustellSetting zsSetting = SelectedZustelldienst;
            dlgConfirm.bSendZustelldienst = false;
            if (zsSetting == null)
            {
                zsSetting = Settings.Default.setZustellungDefault;
            }

            if (zsSetting != null)
            {
                dlgConfirm.bSendZustelldienst = true;
                dlgConfirm.ZustellName = zsSetting.Dienst.ToString();
            }

            fn = "";

            DialogResult dRC = dlgConfirm.ShowDialog();
            if (dRC != DialogResult.OK)
            {
                bSaveLocal = false;
                bSendEtresor = false;
                bSendMail = false;
                bSendZustelldienst = false;
                return dRC;
            }
            bSaveLocal = dlgConfirm.bSaveLocal;
            bSendEtresor = dlgConfirm.bSendEtresor;
            bSendMail = dlgConfirm.bSendMail;
            strEMailAddress = dlgConfirm.strEMailAddress;
            strEtresorAddress = dlgConfirm.strEtresorAddress + "@e-tresor.at";
            bSendZustelldienst = dlgConfirm.bSendZustelldienst;
            if (bSaveLocal)
            {
                fn = dlgConfirm.strLocalFilename;
            }
            return dRC;
        }

        private string MakeFileName(string ReNr, string ReDatum)
        {
            string fn = ReNr.Trim(Path.GetInvalidFileNameChars()) + "-" + ReDatum.Trim('-') + ".XML";
            return fn;
        }

        private string GetItem(XmlDocument xdoc, XmlNamespaceManager nMgr, string xpath)
        {
            XmlNode node = xdoc.SelectSingleNode(xpath, nMgr);
            if (node == null)
            {
                return "";
            }

            string retval = ConvertWhitespaceToSpacesRegex(node.InnerText).Trim(' ');
            // Remove inner Xml whitespace  
            return retval;
        }

        /// <summary>
        /// Converts all whitespace in the string to spaces using Regex.
        /// </summary>
        public static string ConvertWhitespaceToSpacesRegex(string value)
        {
            value = Regex.Replace(value, "[\n\r\t]", " ");
            return value;
        }
        public string Convert_3p0x_to_4p0(string xmldata, string version)
        {
            string position; // 0
            string Beschreibung; // 1
            string ArtikelNr; // 2
            string Einheit; // 3
            string Menge; // 4
            string stueckpreis; // 5
            string mwst; // 6
            string RabattFlag; // 7
            string Rabatt; // 8
            string gesamtbetrag; // 9


            string result = "";
            string tmpStr = xmldata;
            switch (version)
            {
                case ebInterface_Version:
                    break;
                case ebInterface_Version3p0:
                    tmpStr = tmpStr.Replace(ebInterface_Version3p0, ebInterface_Version);
                    // Alle 3p02 mit 4p0 ersetzen, Brutale Methode
                    break;
                case ebInterface_Version3p02:
                    tmpStr = tmpStr.Replace(ebInterface_Version3p02, ebInterface_Version);
                    // Alle 3p02 mit 4p0 ersetzen, Brutale Methode
                    break;
                default:
                    tmpStr = "";
                    break;
            }

            // BillersArticleNumber:

            tmpStr = tmpStr.Replace("<" + xPathArtikelNr3p0x + ">",
                                    "<" + xPathArtikelNr + " " + xPathArtikelNrType + ">"); // Leading Tag
            tmpStr = tmpStr.Replace("</" + xPathArtikelNr3p0x + ">", "</" + xPathArtikelNr + ">"); // Trailing Tag

            // TaxRate wird einfach nicht angegeben!

            // "<eb:TaxRate>"
            // tmpStr = tmpStr.Replace("<eb:TaxRate>", "<eb:TaxRate>");  

            // ReductionAndSurchargeDetails ListLine
            var xdoc = new XmlDocument();
            var xNMgr = new XmlNamespaceManager(xdoc.NameTable);
            xNMgr.AddNamespace("eb", PrefixURLeb);
            xNMgr.AddNamespace("dsig", PrefixURLsig);

            xdoc.LoadXml(tmpStr);

            int icnt = xdoc.SelectNodes(xPathListLine, xNMgr).Count;
            string NodeValue = String.Empty;

            for (int i = 0; i < icnt; i++)
            {
                string StrMenge = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathQuantity, i);
                if (StrMenge != "")
                {
                    Menge = StrMenge;
                    Rabatt = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathReductionRate3p02, i);
                    ArtikelNr = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathArtikelNr, i);
                    Beschreibung = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathDesc, i);
                    stueckpreis = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathUnitPrice, i);
                    mwst = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathTaxRate, i);
                    Einheit = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathUnit, i);
                    gesamtbetrag = GetNodeValue(xdoc, xNMgr, xPathListLine, xPathAmount, i);
                    position = (i + 1).ToString();
                    RabattFlag = Rabatt_false;
                    // ToDo: Aufruf an den Bund anpassen -> Vorlagen enthalten evtl Bestellpositionsnr!!!
                    NodeValue = NodeValue + LineItemDetail2XML(
#if ebInterface4Bund
"",
                        "",
#endif
 position, // 0
                        Beschreibung, // 1
                        ArtikelNr, // 2
                        Einheit, // 3
                        Menge, // 4
                        stueckpreis, // 5
                        mwst, // 6
                        RabattFlag, // 7
                        Rabatt, // 8
                        gesamtbetrag, // 9
                        "",
                        ""
                                                );
                }
            }
            XmlNode ItemNode = xdoc.SelectSingleNode(xPathItemList, xNMgr);
            ItemNode.InnerXml = NodeValue;


            result = xdoc.InnerXml;
            return result;
        }

        private string LineItemDetail2XML(
#if ebInterface4Bund
            string orderId4Bund,
            string bestellPosNr,
#endif
           string position, // 0
           string Beschreibung, // 1
           string ArtikelNr, // 2
           string Einheit, // 3
           string Menge, // 4
           string stueckpreis, // 5
           string mwst, // 6
           string RabattFlag, // 7
           string Rabatt, // 8
           string gesamtbetrag, // 9
           string nichtsteuerbar, // 10
            string gesBetragUnrabattiert
            )
        {
            string retval = String.Empty;
            string rabattXML = String.Empty;
            if (RabattFlag == Rabatt_true)
            {
                rabattXML = String.Format(ReductionAndSurchargeXML, Rabatt, gesBetragUnrabattiert);
            }
#if ebInterface4Bund
            // InvoiceRecipientsOrderReference für den Bund
            // OrderID muss einen Wert enthalten
            // ToDo bestellpos im Kontext mit OrderID prüfen!
            string bestPosXML = "";
            if (bestellPosNr != "")
            {
                bestPosXML = string.Format(InvoiceRecipientsOrderReferenceXML, orderId4Bund, bestellPosNr);
            }
            rabattXML = rabattXML + bestPosXML;
#endif
            retval = String.Format(DetailItemXml,
                                   position, // 0
                                   Beschreibung, // 1
                                   ArtikelNr, // 2
                                   Einheit, // 3
                                   Menge, // 4
                                   stueckpreis, // 5
                                   mwst, // 6
                                   RabattFlag, // 7
                                   rabattXML, // 8
                                   gesamtbetrag, // 9
                                   nichtsteuerbar // 10
                );

            return retval;
        }

        public string LoadXMLTemplate()
        {
            string XMLFile = String.Empty;
            // StreamWriter XMLWriter;
            var sDlg = new OpenFileDialog();
            sDlg.InitialDirectory = Settings.Default.setTemplatePath;
            sDlg.Filter = "XML files (*.xml)|*.xml|All files (*.*)|*.*";
            sDlg.FilterIndex = 1;
            sDlg.RestoreDirectory = true;
            string xmlData;
            try
            {
                if (sDlg.ShowDialog() == DialogResult.OK)
                {
                    XMLFile = sDlg.FileName;
                    var ResRd = new StreamReader(XMLFile);
                    if (ResRd != null)
                    {
                        xmlData = ResRd.ReadToEnd();
                        ResRd.Close();
                        var xdoc = new XmlDocument();
                        var xTemp = new XmlDocument();
                        xTemp.LoadXml(xmlData);
                        // xdoc auf ebInterface untersuchen
                        XmlNode xmlnsebNode = xTemp.DocumentElement.Attributes.GetNamedItem("xmlns:eb");
                        if (xmlnsebNode == null)
                        {
                            MessageBox.Show(
                                "Die XML Datei enthälte keine ebInterface Definitionen. Die Vorlage wurde nicht geladen",
                                "XML Vorlage laden", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return (String.Empty); // XML Daten sind nicht gültig
                        }
                        string xmlnseb = xmlnsebNode.InnerText;
                        string loadVersion = "";
                        if (xmlnseb != PrefixURLeb)
                        {
                            string[] UriParts = xmlnseb.Split('/');
                            loadVersion = @"/" + UriParts[UriParts.Length - 2] + @"/";
                            string tmpStr = xmlData;
                            switch (loadVersion)
                            {
                                case ebInterface_Version:
                                    break;
                                case ebInterface_Version3p0:
                                case ebInterface_Version3p02:
                                    xmlData = Convert_3p0x_to_4p0(xmlData, loadVersion);
                                    break;
                                default:
                                    xmlData = "";
                                    break;
                            }
                        }

                        if (xmlData == "")
                        {
                            MessageBox.Show(
                                "Die ebInterface Datei " + sDlg.FileName +
                                " wird nicht unterstützt. Erstellen Sei die Vorlage neu.",
                                "XML Vorlage laden", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return (String.Empty); // XML Daten sind nicht gültig
                        }

                        xdoc.LoadXml(xmlData);
                        var xNMgr = new XmlNamespaceManager(xdoc.NameTable);
                        xNMgr.AddNamespace("eb", PrefixURLeb);
                        xNMgr.AddNamespace("dsig", PrefixURLsig);
                        string strGenSys = xdoc.DocumentElement.GetAttribute(xAttrGeneratingSystem);

                        bool isValid = false;
                        if ((strGenSys != null) && (strGenSys.Length >= DocumentTitleVorlage.Length))
                        {
                            string loadedTitle = strGenSys.Substring(0, DocumentTitleVorlage.Length);
                            switch (loadedTitle)
                            {
                                case DocumentTitleVorlage:
                                case DocumentTitleVorlage3P0:
                                    isValid = true;
                                    break;
                                default:
                                    isValid = false;
                                    break;
                            }
                        }
                        if (isValid == false)
                        {
                            // ebDoc.ThisDocument.SetFehlerText(""); // XML nicht geladen.
                            MessageBox.Show(
                                "Die XML Vorlage wurde nicht mit ebInterface 3.0, 3.02 oder 4.0 Word Formular Vorlage erstellt. Die Vorlage wurde nicht geladen",
                                "XML Vorlage laden", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            return (String.Empty); // XML Daten sind nicht gültig
                        }
                        int[] nRet = new int[4];
                        int iret;
                        DateTime cInvDateFromTemplate;
                        nRet[0] = CheckDate(xdoc.SelectSingleNode(xPathInvDate, xNMgr).InnerText, out cInvDateFromTemplate);
                        iret = nRet[0] != 0 ? 1 : 0;
                        DateTime cDueDate;
                        nRet[1] = CheckDate(xdoc.SelectSingleNode(xPathPaymtDuedate, xNMgr).InnerText, out cDueDate);
                        iret = iret + (nRet[1] != 0 ? 1 : 0);
                        DateTime cDeliveryDate;
                        nRet[2] = CheckDate(xdoc.SelectSingleNode(xPathDeliveryDate, xNMgr).InnerText, out cDeliveryDate);
                        iret = iret + (nRet[2] != 0 ? 1 : 0);
                        nRet[3] = (xdoc.SelectSingleNode(xPathInvNumber, xNMgr).InnerText == String.Empty) ? 0 : 1;
                        iret = iret + (nRet[3] != 0 ? 1 : 0);

                        DialogResult rc = DialogResult.No;
                        Globals.ThisDocument.Rechnungsdatum = cInvDateFromTemplate;
                        Globals.ThisDocument.RechnungsdatumInTemplate = cInvDateFromTemplate;
                        Globals.ThisDocument.FaelligDatum = cDueDate;

                        if (iret > 0)
                        {
                            rc = MessageBox.Show(
                                "Sollen alle Werte übernommen werden?\n Rechnungsnummer: " + xdoc.SelectSingleNode(xPathInvNumber, xNMgr).InnerText +
                                "\nRechnungsdatum " + cInvDateFromTemplate.ToShortDateString() +
                                "\nFälligkeitsdatum " + cDueDate.ToShortDateString() +
                                "\nLieferdatum " + cDeliveryDate.ToShortDateString(),
                                "Werte aus der Vorlage", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                        }
                        if (rc == DialogResult.No)
                        {
                            iret = nRet[0];
                            if (iret < 0)
                            {
                                Globals.ThisDocument.Rechnungsdatum = cInvDateFromTemplate;
                                // cInvDate = DateTime.Today;
                                rc =
                                    MessageBox.Show(
                                        "Rechnungsdatum in der Vorlage ist veraltet. Soll das Rechnungsdatum auf " +
                                        DateTime.Today.ToShortDateString() + " gesetzt werden?",
                                        "Vorlage laden", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                                if (rc == DialogResult.Yes)
                                {
                                    Globals.ThisDocument.Rechnungsdatum = DateTime.Today;
                                    ClearNodeContent(xdoc, xPathInvDate, xNMgr,
                                                     FormatDate(Globals.ThisDocument.Rechnungsdatum));
                                }
                            }
                            iret = nRet[1]; // Fälligkeit
                            Globals.ThisDocument.FaelligDatum = cInvDateFromTemplate;
                            cDueDate = UpdateDate(cDueDate, cInvDateFromTemplate);
                            rc =
                                MessageBox.Show(
                                    "Fälligkeitdatum in der Vorlage ist veraltet. Soll das Fälligkeitdatum auf " +
                                    cDueDate.ToShortDateString() + " gesetzt werden?",
                                    "Vorlage laden", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                            if (rc == DialogResult.Yes)
                            {
                                Globals.ThisDocument.FaelligDatum = cDueDate;
                                ClearNodeContent(xdoc, xPathPaymtDuedate, xNMgr,
                                                 FormatDate(Globals.ThisDocument.FaelligDatum));
                            }

                            // xPathDeliveryDate
                            cDeliveryDate = UpdateDate(cDeliveryDate, cInvDateFromTemplate);
                            rc =
                                MessageBox.Show(
                                    "Lieferdatum in der Vorlage ist veraltet. Soll das Lieferdatum auf " +
                                    cDeliveryDate.ToShortDateString() + " gesetzt werden?",
                                    "Vorlage laden", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                            if (rc == DialogResult.Yes)
                            {
                                ClearNodeContent(xdoc, xPathDeliveryDate, xNMgr, FormatDate(cDeliveryDate));
                            }
                            //    iret = nRet[2];
                            //if (iret < 0)
                            //{

                            //}

                            string rnr = xdoc.SelectSingleNode(xPathInvNumber, xNMgr).InnerText;
                            if (rnr != "")
                            {

                                rc =
                                    MessageBox.Show(
                                        "Die Vorlage enthält eine Rechnungsnummer. Soll die Rechnungsnummer gelöscht werden?",
                                        "Vorlage laden", MessageBoxButtons.YesNo, MessageBoxIcon.Exclamation);
                                if (rc == DialogResult.Yes)
                                {
                                    ClearNodeContent(xdoc, xPathInvNumber, xNMgr, "");
                                }
                            }
                        }

                        xmlData = MergeXML(xdoc, xNMgr);
                        // InvCurrency = "";
                        // xmlData = xdoc.InnerXml;
                        return (xmlData);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler beim Lesen der XML Vorlage " + XMLFile + "\n" + ex.Message, "Lesen XML Vorlage",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return String.Empty;
        }

        private static DateTime UpdateDate(DateTime cTargetDate, DateTime cInvDate)
        {
            int diff = cTargetDate.Subtract(cInvDate).Days;
            if (diff > 0)
            {
                return Globals.ThisDocument.Rechnungsdatum.AddDays(diff);
            }
            return DateTime.Today;
        }

        private int CheckDate(string xDate, out DateTime cDate)
        {
            DateTime then;
            Boolean DateOK = DateTime.TryParse(xDate, out then);
            if (DateOK == false)
            {
                cDate = DateTime.Today;
                return 0;
            }
            cDate = then;
            return (DateTime.Compare(then, DateTime.Today));
        }

        private string MergeXML(XmlDocument xdocTemplate, XmlNamespaceManager xNmgr)
        {
            string LeerXml = Globals.ThisDocument.GetFromXMLResource(ebInterfaceLeer);
            string xmldata = "";
            var xDocLeer = new XmlDocument();
            xDocLeer.LoadXml(LeerXml);
            var xLeerNMgr = new XmlNamespaceManager(xDocLeer.NameTable);
            xLeerNMgr.AddNamespace("eb", PrefixURLeb);
            xLeerNMgr.AddNamespace("dsig", PrefixURLsig);
            Document doc = Globals.ThisDocument.Application.ActiveDocument;
            XmlNode inDoc;
            XmlNode inTempl;
            foreach (ContentControl wCC in doc.ContentControls)
            {
                string xPwCC = wCC.XMLMapping.XPath;
                Debug.WriteLine("Merging: " + xPwCC);
                Debug.WriteLine("Feld:" + wCC.Title);
                if (xPwCC != null)
                {
                    inDoc = xDocLeer.SelectSingleNode(xPwCC, xLeerNMgr);
                    if (inDoc == null)
                    {
                        throw new MissingFieldException("Merge Template: xPath=" + xPwCC +
                                                        " in leerem XML nicht geunden.");
                    }
                    inTempl = xdocTemplate.SelectSingleNode(xPwCC, xNmgr);
                    if (inTempl != null)
                    {
                        Debug.WriteLine(inDoc.Name + "=" + inDoc.InnerText + "; " + inTempl.Name + "=" +
                                        inTempl.InnerText);
                        inDoc.InnerText = inTempl.InnerText;
                    }
                }
            }
            // xPathItemList
            ReplaceLists(xPathItemList, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            // xPathTaxVATList
            ReplaceLists(xPathTaxVATList, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            // xPathDiscntPmntCond
            ReplaceLists(xPathDiscntPmntCond, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);

            // xPathBankLand xPathDocumentType xPathDocumentTitle xPathCurrency
            ReplaceLists(xPathBankLand, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            ReplaceLists(xPathDocumentType, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            ReplaceLists(xPathDocumentTitle, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);
            ReplaceLists(xPathCurrency, xdocTemplate, xNmgr, xDocLeer, xLeerNMgr);

            xmldata = xDocLeer.OuterXml;
            return xmldata;
        }

        private void CopyValue(string xPList, XmlDocument FromDoc, XmlNamespaceManager xFromNmgr, XmlDocument xToDoc,
                               XmlNamespaceManager xToNmgr)
        {
            XmlNode xFromNode = FromDoc.SelectSingleNode(xPList, xFromNmgr);
            if (xFromNode == null)
            {
                return;
            }
            XmlNode xToNode = xToDoc.SelectSingleNode(xPList, xToNmgr);
            if (xToNode == null)
            {
                return;
            }
        }

        private void ReplaceLists(string xPList, XmlDocument FromDoc, XmlNamespaceManager xFromNmgr, XmlDocument xToDoc,
                                  XmlNamespaceManager xToNmgr)
        {
            XmlNode xFromNode = FromDoc.SelectSingleNode(xPList, xFromNmgr);
            if (xFromNode == null)
            {
                return;
            }
            XmlNode xToNode = xToDoc.SelectSingleNode(xPList, xToNmgr);
            if (xToNode == null)
            {
                return;
            }
            xToNode.InnerXml = xFromNode.InnerXml;
            return;
        }

        private void ClearNodeContent(XmlDocument xdoc, string xPathToClear, XmlNamespaceManager xNMgr, string value)
        {
            XmlNode xnode = xdoc.SelectSingleNode(xPathToClear, xNMgr);
            if (xnode != null)
            {
                xnode.InnerText = value;
            }
        }

        public int SendMail(string ToAdress, string etresorAdress, string Subject, string MsgBody, string XmlFileName)
        {
            string pdfFileName = Path.Combine(Path.GetTempPath(), Path.GetFileNameWithoutExtension(XmlFileName) + ".pdf");
            Document doc = Globals.ThisDocument.Application.ActiveDocument;
            SaveDocumentAsPDF(ref doc, pdfFileName);

#if !DEBUG
		            var outlook = new Application();
            var mail = (_MailItem)outlook.CreateItem(OlItemType.olMailItem);


            if (ToAdress != "")
            {
                mail.To = ToAdress;
                if (strEtresorAddress != "")
                {
                    mail.BCC = strEtresorAddress;
                }
            }
            else
            {
                if (strEtresorAddress == "")
                {
                    return 0;
                }
                mail.To = strEtresorAddress;
            }

            mail.Subject = Subject;
            mail.Body = MsgBody;
            mail.Attachments.Add(XmlFileName, OlAttachmentType.olByValue, 1, null);
            mail.Attachments.Add(pdfFileName, OlAttachmentType.olByValue, 1, null);
            // mail.Send();
            mail.Display(true);

            mail = null;
            outlook = null;
  
#endif
            return 0;
        }

        private string GetNameFromXMLError(string errorTxt)
        {
            string[] temp = errorTxt.Split('\t');
            return temp[0];
        }

        private string AppendRetVal(string oldval, string addval)
        {
            string retVal;
            if (oldval == "")
            {
                retVal = addval;
            }
            else
            {
                retVal = oldval + "\n" + addval;
            }
            return retVal;
        }

        /// <summary>
        /// Alle Eingabefelder prüfen
        /// </summary>
        /// <returns></returns>
        private string VerifyAllCC()
        {
            Document wDoc = Globals.ThisDocument.Application.ActiveDocument;
            string retVal = String.Empty;
            int len = 0;

            ContentControl CCBankName = null;
            ContentControl CCBankAccountNr = null;
            ContentControl CCBankAccountOwner = null;
            ContentControl CCBankCode = null;
            ContentControl CCBankIBAN = null;
            ContentControl CCBankBIC = null;
            string eText;
            foreach (ContentControl wCC in wDoc.ContentControls)
            {
                Debug.WriteLine(wCC.ID + " " + wCC.PlaceholderText.Value + "/" + wCC.Tag + "<" + wCC.Range.Text);
                // Verifiy Fields
                string ccTag = "";
                if (wCC.Tag != null)
                {
                    ccTag = wCC.Tag.ToLower();
                }
                switch (ccTag)
                {
                    case CCTag_NichtLeer:
                        len = 0;
                        if (wCC.Range.Text != null)
                        {
                            len = wCC.Range.Text.Length;
                        }
                        if (wCC.ShowingPlaceholderText || (len == 0))
                        {
                            retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Darf nicht leer sein.");
                        }
                        break;
                    case CCTag_VAT:
                        if (Globals.ThisDocument.BetragInklMwSt >= 10000)
                        {
                            if (wCC.ShowingPlaceholderText || (wCC.Range.Text == "00000000"))
                            {
                                retVal = AppendRetVal(retVal,
                                                      wCC.PlaceholderText.Value + "\t" +
                                                      "Empfänger VAT-ID fehlt bei Rechnungsbetrag>10000.");
                            }
                        }
                        break;
                    case CCTag_Num:
                        if (wCC.ShowingPlaceholderText != true)
                        {
                            try
                            {
                                decimal decVal = Decimal.Parse(wCC.Range.Text);
                            }
                            catch (Exception)
                            {
                                retVal = AppendRetVal(retVal, wCC.Title + "\t" + "ist nicht numerisch.");
                            }
                        }
                        else
                        {
                            retVal = AppendRetVal(retVal, wCC.PlaceholderText.Value + "\t" + "Darf nicht leer sein.");
                        }
                        break;
                    default:
                        break;
                }
                switch (wCC.XMLMapping.XPath)
                {
                    case xPathOrderRefID:
                        // RefDate ohne OrderID nicht möglich
                        // 
#if ebInterface4Bund
                        if (wCC.ShowingPlaceholderText || (wCC.Range.Text == " ")) // OrderID ist leer          
                        {
                            retVal = AppendRetVal(retVal,
                                                  "Auftragsreferenz fehlt.");
                        }
                        else
                        {
                            string retOrderId = ExtensionMethods.ExtensionMethods.ValidateOrderRefBund(wCC.Range.Text);
                            if (retOrderId != "")
                            {
                                retVal = AppendRetVal(retVal, retOrderId);
                            }
                            else // OrderID is Valid
                            {

                                bool oidValid = InvDetails.TblInvDetails.IsDetailsTableValid(out eText);
                                if (!oidValid)
                                {
                                    retVal = AppendRetVal(retVal, eText);
                                }
                            }
                        }
#else
                        if (wCC.ShowingPlaceholderText || (wCC.Range.Text == " ")) // OrderID ist leer          
                        {
                            if (IsDate(Globals.ThisDocument.CC_OrderDate.Text))
                            {
                                retVal = AppendRetVal(retVal,
                                                      "Bestelldatum ohne Angabe der Bestellreferenz nicht möglich.");
                            }
                        }
#endif
                        break;
                    case xPathPaymtDuedate:
                        // Fälligkeitsdatum muss => Rechnungsdatum sein

                        if (IsDueDateValid(FormatDateVonXML(wCC.Range.Text), out eText) == false)
                        {
                            retVal = AppendRetVal(retVal, eText);
                        }
                        break;
                    case xPathBillerVATID:
                    case xPathInvRecVATID:
                        if (wCC.ShowingPlaceholderText != true)
                        {
                            if (!IsValidVATID(wCC.Range.Text))
                            {
                                retVal = AppendRetVal(retVal,
                                                      wCC.PlaceholderText.Value +
                                                      " nicht plausibel bzw. nicht 00000000.");
                            }
                        }
                        break;
                    //case xPathBankAcctNr:
                    //    CCBankAccountNr = wCC;
                    //    break;
                    case xPathBankName:
                        CCBankName = wCC;
                        break;
                    //case xPathBankBLZ:
                    //    CCBankCode = wCC;
                    //    break;
                    case xPathBankBIC:
                        CCBankBIC = wCC;
                        break;
                    case xPathBankAcctOwner:
                        CCBankAccountOwner = wCC;
                        break;
                    case xPathBankIBAN:
                        CCBankIBAN = wCC;
                        break;
                    default:
                        break;
                }

            }



            string errText;
            bool kvb = IsKontoverbindungValid(
                CCBankName,
                // CCBankAccountNr,
                CCBankAccountOwner,
                // CCBankCode,
                CCBankIBAN,
                CCBankBIC, out errText);


            if (kvb != true)
            {
                retVal = AppendRetVal(retVal, errText);
            }

            return retVal;
        }

        private bool IsKontoverbindungValid(ContentControl CCBankName,
                                            ContentControl CCBankAccountOwner,
                                            ContentControl CCBankIBAN,
                                            ContentControl CCBankBIC, out string errText)
        {
            errText = "";
            bool inhaberGemotzt = false;
#if ebInterface4Bund
            if (CCBankAccountOwner.ShowingPlaceholderText)
            {
                errText = AppendRetVal(errText, "Kontoinhaber fehlt");
            }
#else
            // Wenn alle den Placeholder Text zeigen -> ist es gut
            if (CCBankAccountOwner.ShowingPlaceholderText &&
                CCBankBIC.ShowingPlaceholderText &&
                CCBankIBAN.ShowingPlaceholderText &&
                CCBankName.ShowingPlaceholderText)
            {
                errText = "";
                return true;
            }

#endif
            if (CCBankBIC.ShowingPlaceholderText)
            {
                errText = AppendRetVal(errText, "BIC fehlt.");

            }
            if (CCBankIBAN.ShowingPlaceholderText)
            {
                errText = AppendRetVal(errText, "IBAN fehlt.");
            }
            //}
            if (errText == "")
            {
                return true;
            }
            return false;
        }



        /// <summary>
        /// Prüft die übergebene VATID auf Plausibilität. Die genauen Länderregeln werden nicht geprüft.
        /// Prüfungen:
        /// = "00000000" oder minLänge>=8 beginnend mit 2 stelligem Ländercode gemäss Tabelle
        /// </summary>
        /// <param name="VAT2Verify">Zu prüfende VAT ID</param>
        /// <returns></returns>
        public bool IsValidVATID(string VAT2Verify)
        {
            if (VAT2Verify == "00000000")
            {
                return true;
            }
            if (VAT2Verify.Length >= 8)
            {
                foreach (string item in VAT_Country_Code)
                {
                    if (item == VAT2Verify.Substring(0, 2))
                    {
                        return true;
                    }
                }
            }
            return false;
        }

        private bool IsDate(string xDate)
        {
            DateTime x;
            return (DateTime.TryParse(xDate, out x));
        }

        private bool IsDueDateValid(string dueDate, out string errorText)
        {
            if (!IsDate(dueDate))
            {
                errorText = "Das Fälligkeitsdatum ist ungültig.";
                return false;
            }
            DateTime dtDueDate = DateTime.Parse(dueDate);
            DateTime dtInvDate = DateTime.Parse(Globals.ThisDocument.CC_InvoiceDate.Text);
            if (DateTime.Compare(dtDueDate, dtInvDate) < 0)
            {
                errorText = "Date Fälligkeitsdatum liegt vor dem Rechnungsdatum.";
                return false;
            }

            if (!InvDetails.TblInvSkonto.IsSkontoDateValid(dtDueDate))
            {
                errorText = "Das Fälligkeitsdatum liegt vor einer Skontofrist";
                return false;
            }
            errorText = "";
            return true;

        }

        private ContentControl FindCCfromXMLMapping(string name)
        {
            Document wDoc = Globals.ThisDocument.Application.ActiveDocument;
            foreach (ContentControl wCC in wDoc.ContentControls)
            {
                if (wCC.XMLMapping.XPath == name)
                {
                    return wCC;
                }
            }
            return null;
        }

        private string GetPlaceholderText4Error(string eText)
        {
            string wCCName;
            ContentControl wCCTemp;
            wCCName = GetNameFromXMLError(eText);
            if (wCCName == "")
            {
                return ("?Name unbekannt?");
            }
            wCCTemp = FindCCfromXMLMapping(wCCName);
            if (wCCTemp == null)
            {
                return ("?XMLMapping unbekannt?");
            }
            return (wCCTemp.PlaceholderText.Value);
        }


        private XmlSchemaSet GetXmlSchemas()
        {
            var xSchema = new XmlSchemaSet();

            Assembly Asm = Assembly.GetExecutingAssembly();
            XmlReader rdr = XmlReader.Create(Asm.GetManifestResourceStream(xmlDsigXSDFile));
            XmlReader rdr1 = XmlReader.Create(Asm.GetManifestResourceStream(InvoiceXSDFile));

            try
            {
                xSchema.Add(PrefixURLsig, rdr);
                xSchema.Add(PrefixURLeb, rdr1);
                xSchema.Compile();
                return xSchema;
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei Add Schema\r\n" + ex.Message);
            }
            return null;
        }

        private bool IsEbInterfaceXMLValid(XmlDocument xdoc, string filename, bool isDoc)
        {
            var xmlChecker = new XmlValidator();
            XmlValidator.XmlValidatorResult result;
            Globals.ThisDocument.SetFehlerText(""); // Fehlerliste löschen
            string errorTxt = String.Empty;
            string temp = String.Empty;
            // string schemaUri = null;

            try
            {
                xmlChecker.SchemaSet = GetXmlSchemas();


                if (isDoc)
                {
                    result = xmlChecker.ValidateXmlDocument(xdoc, ValidationType.Schema, null);
                }
                else
                {
                    result = xmlChecker.ValidateXmlFile(filename, ValidationType.Schema, null);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei XML Validierung von '" + xdoc + "'.\r\n" +
                                ex.Message + "\r\n",
                                "XML Validieren", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return false;
            }


            switch (result)
            {
                case XmlValidator.XmlValidatorResult.Valid:
                    return true;
                case XmlValidator.XmlValidatorResult.ErrorsExists:
                    errorTxt = "Fehler im XML Dokument '" + xdoc + "'.\r\n";
                    foreach (string t in xmlChecker.Errors)
                    {
                        temp = t;
                        temp = GetPlaceholderText4Error(temp) + "\t" + temp;
                        errorTxt = errorTxt + "\r\n" + temp;
                    }
                    if (xmlChecker.Warnings.Count > 0)
                    {
                        errorTxt = errorTxt + "\r\nWarnungen im XML Dokument '" + xdoc + "'.\r\n";
                        foreach (string t in xmlChecker.Warnings)
                        {
                            temp = t;
                            temp = GetPlaceholderText4Error(temp) + "\t" + temp;
                            errorTxt = errorTxt + "\r\n" + temp;
                        }
                    }

                    Debug.WriteLine(errorTxt);
                    // MessageBox.Show(errorTxt);
                    Globals.ThisDocument.SetFehlerText(errorTxt);
                    return false;
                // break;
                case XmlValidator.XmlValidatorResult.WarningsExists:
                    errorTxt = "Warnungen im XML Dokument '" + xdoc + "'.\r\n";
                    foreach (string t in xmlChecker.Warnings)
                    {
                        temp = t;
                        temp = GetPlaceholderText4Error(temp) + "\t" + temp;
                        errorTxt = errorTxt + "\r\n" + temp;
                    }
                    Debug.WriteLine(errorTxt);
                    // MessageBox.Show(errorTxt);
                    Globals.ThisDocument.SetFehlerText(errorTxt);
                    return true;
                // break;
                default:
                    break;
            }
            return false;
        }

        public string GetNodeValue(XmlDocument XMLPart, XmlNamespaceManager xNmgr, string xPathList, string XMLFieldName,
                                   int i)
        {
            string XMLField = String.Empty;
            string value = String.Empty;
            XMLField = String.Format(xPathList + "[{0}]", i + 1) + "/" + XMLFieldName;
            XmlNode xn = XMLPart.SelectSingleNode(XMLField, xNmgr);
            value = xn.InnerText;
            return (value);
        }


        public string GetNodeValue(CustomXMLPart XMLPart, string xPathList, string XMLFieldName)
        {
            string XMLField = String.Empty;
            string value = String.Empty;
            XMLField = xPathList + "/" + XMLFieldName;
            CustomXMLNode xn = XMLPart.SelectSingleNode(XMLField);
            if (xn != null)
            {
                value = xn.Text;
            }
            return (value);

        }


        public string GetNodeValue(CustomXMLPart XMLPart, string xPathList, string XMLFieldName, int i)
        {
            string XMLField = String.Empty;
            string value = String.Empty;
            XMLField = String.Format(xPathList + "[{0}]", i + 1) + "/" + XMLFieldName;
            CustomXMLNode xn = XMLPart.SelectSingleNode(XMLField);
            if (xn != null)
            {
                value = xn.Text;
            }
            return (value);
        }

        private string FormatDecimal4(decimal val)
        {
            string retval = val.ToString("#0.0000", CultureInfo.InvariantCulture);
            return (retval);
        }


        private string FormatDecimal(decimal val)
        {
            string retval = val.ToString("#0.00", CultureInfo.InvariantCulture);
            return (retval);
        }

        private string FormatDateVonXML(string datum)
        {
            if (datum == "")
            {
                return datum;
            }
            try
            {
                string rdat = FormatDate(DateTime.Parse(datum));
                return rdat;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        private string FormatDate(DateTime datum)
        {
            string retval = datum.ToString("yyyy-MM-dd", CultureInfo.InvariantCulture);
            return retval;
        }

        private decimal ConvertXML2Decimal(string wert)
        {
            if (wert == "")
            {
                return (0);
            }
            string wert2 = wert.Replace(".", ",");
            decimal dec = Decimal.Parse(wert2);
            return (dec);

        }

        /// <summary>
        /// Erzeugt aus der Detail Tabelle die XML Ausgabe
        /// </summary>
        /// <returns></returns>
#if ebInterface4Bund
        public string Details2XML(string orderId4Bund)
        {
            string bestellPosNr;
#else            
        public string Details2XML()
        {
#endif
            string position; // 0
            string Beschreibung; // 1
            string ArtikelNr; // 2
            string Einheit; // 3
            string Menge; // 4
            string stueckpreis; // 5
            string mwst; // 6
            string RabattFlag; // 7
            string Rabatt; // 8
            string gesamtbetrag; // 9
            string gesamtBertragUnrabattiert;
            string NodeValue = String.Empty;
            string NichtSteuerbar = String.Empty;
            decimal gesBetrUnrabattiert;

            try
            {
                DataRow[] rows = InvDetails.TblInvDetails.Select();
                int i = 1;
                foreach (DsInvoice.TblInvDetailsRow dsRow in rows)
                {
                    ArtikelNr = dsRow.SpArtikelNr;
                    Menge = FormatDecimal(dsRow.SpMenge);
                    Beschreibung = dsRow.SpBezeichnung;
                    stueckpreis = FormatDecimal4(dsRow.SpEinzelpreis);
                    Einheit = dsRow.SpEinheit;
                    position = (i++).ToString();
                    gesamtbetrag = FormatDecimal(dsRow.SpGesamtBetrag);
                    gesBetrUnrabattiert = dsRow.SpEinzelpreis*dsRow.SpMenge;
                    gesamtBertragUnrabattiert = FormatDecimal(gesBetrUnrabattiert);
                    //NichtSteuerbar = string.Empty;
                    //if (dsRow.SpMwSt == -1)
                    //{
                    //    mwst = FormatDecimal(0);
                    //    NichtSteuerbar = " eb:TaxCode=\"ATXXX\"";
                    //}
                    //else
                    //{
                    mwst = FormatDecimal(dsRow.SpMwSt);
                    //}
                    Rabatt = FormatDecimal(dsRow.SpRabattProz);
                    RabattFlag = Rabatt_false;
                    if (dsRow.SpRabattProz != 0)
                    {
                        RabattFlag = Rabatt_true;
                    }
#if ebInterface4Bund
                    bestellPosNr = dsRow.SpBestellBezug;
#endif

                    NodeValue = NodeValue + LineItemDetail2XML(
#if ebInterface4Bund
orderId4Bund,
                        bestellPosNr,
#endif
 position, // 0
                        Beschreibung, // 1
                        ArtikelNr, // 2
                        Einheit, // 3
                        Menge, // 4
                        stueckpreis, // 5
                        mwst, // 6
                        RabattFlag, // 7
                        Rabatt, // 8
                        gesamtbetrag, // 9
                        NichtSteuerbar, // 10
                        gesamtBertragUnrabattiert
                                                );
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei Erstellen der XML für Detailzeilen" + ex.Message, "XML Erstellen",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }

            return (NodeValue);
        }

        public string MwSt2XML()
        {
            string NodeValue = String.Empty;
            if (Settings.Default.SetVStBerechtigt == false)
            {
                // Der Benutzer ist nicht Vorsteuerabzugsberechtigt
                NodeValue = String.Format(VAT_TaxExemption, Settings.Default.SetVStText);
            }
            else
            {
                try
                {
                    DataRow[] dsRows = InvDetails.TblMwStSummen.Select();
                    foreach (DsInvoice.TblMwStSummenRow row in dsRows)
                    {
                        NodeValue = NodeValue + String.Format(VatItemXML,
                                                              FormatDecimal(row.spBasisBetrag),
                                                              FormatDecimal(row.spMwSt),
                                                              FormatDecimal(row.spMwStBetrag));
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show("Fehler bei Erstellen XML für MwST." + ex.Message, "XML Erstellen",
                                    MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw;
                }
            }
            return (NodeValue);
        }

        private XmlNode SetCountry(XmlNode xin, string CtryLong, string CtryShort)
        {
            XmlNode xout = xin;
            var xel = (XmlElement)xout;
            xel.SetAttribute(xAttrCountryCode, PrefixURLeb, CtryShort);
            xout.InnerText = CtryLong;
            return xout;
        }

        public string Skonto2XML()
        {
            string NodeValue = String.Empty;

            try
            {
                DataRow[] dsRows = InvDetails.TblInvSkonto.Select();
                foreach (DsInvoice.TblInvSkontoRow row in dsRows)
                {
                    NodeValue = NodeValue + String.Format(DiscItemXML,
                                                          FormatDate(row.SpBisDatum),
                                                          FormatDecimal(row.SpSkontoProz),
                                                          FormatDecimal(row.spSkontoBetrag));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("Fehler bei Erstellen XML für Skonto." + ex.Message, "XML Erstellen",
                                MessageBoxButtons.OK, MessageBoxIcon.Error);
                throw;
            }
            return (NodeValue);
        }

        public void LoadSkontoTable(CustomXMLPart XMLPart, DsInvoice myDs)
        {
            decimal SktoPrz;
            DateTime SktoDate;
            DsInvoice.TblInvSkontoRow myRow;
            // string ReDatum = GetNodeValue(XMLPart, xPathDiscntLine,xPathDiscntDueDate); // Fälligkeitsdatum

            // DateTime tempDate = Globals.ThisDocument.Rechnungsdatum;
            // DateTime.TryParse(ReDatum, out tempDate) ? tempDate : Globals.ThisDocument.Rechnungsdatum;
            myDs.TblInvSkonto.Clear();
            int icnt = XMLPart.SelectNodes(xPathDiscntLine).Count;
            if (icnt == 0)
            {
                return;
            }
            try
            {
                for (int i = 0; i < icnt; i++)
                {
                    string StrSktoPrz = GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntProz, i);
                    if (StrSktoPrz != "")
                    {
                        SktoPrz = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntProz, i));
                        SktoDate = DateTime.Parse(GetNodeValue(XMLPart, xPathDiscntLine, xPathDiscntDate, i));
                        myRow =
                            (DsInvoice.TblInvSkontoRow)
                            myDs.TblInvSkonto.Rows.Add(new object[] { SktoPrz, SktoDate, 0, 0, 0 });
                        myDs.TblInvSkonto.UpdateSkontoTage(myRow);
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public bool LoadDetailsTable(CustomXMLPart XMLPart, DsInvoice myDs)
        {
            decimal Menge;
            decimal RabattProz;
            string ArtikelNr;
            string Beschreibung;
            decimal stueckpreis;
            string Einheit;
            decimal Mwst;
            string Taxcode;
#if ebInterface4Bund
            string orderRef;
#endif

            try
            {
                myDs.TblInvDetails.Clear();
                int icnt = XMLPart.SelectNodes(xPathListLine).Count;

                // DsDetails myDS = new DsDetails();


                for (int i = 0; i < icnt; i++)
                {
                    string StrMenge = GetNodeValue(XMLPart, xPathListLine, xPathQuantity, i);
                    if (StrMenge != "")
                    {
                        Menge = ConvertXML2Decimal(StrMenge);
                        RabattProz = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathReductionRate, i));
                        ArtikelNr = GetNodeValue(XMLPart, xPathListLine, xPathArtikelNr, i);
                        Beschreibung = GetNodeValue(XMLPart, xPathListLine, xPathDesc, i);
                        stueckpreis = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathUnitPrice, i));
                        // Taxcode = GetNodeValue(XMLPart, xPathListLine, xPathTaxCode, i);
                        Mwst = 0;
                        if (Settings.Default.SetVStBerechtigt) // "nomale" Steuersätzw 
                        {
                            Mwst = ConvertXML2Decimal(GetNodeValue(XMLPart, xPathListLine, xPathTaxRate, i));
                        }
                        else
                        {
                            Mwst = 0;
                        }

                        if (Globals.ThisDocument.IsMwStInSettings(Mwst) == false)
                        {
                            throw (new Exception("Der MwSt Satz " + Mwst.ToString("0.00") +
                                                 " in der XML Vorlage ist nicht in den aktuellen Einstellungen eingetragen.\n" +
                                                 "Ergänzen Sie die MwSt Tabelle in den Einstellungen um diesen Wert und laden Sie dann die XML Vorlage erneut."));
                        }
#if ebInterface4Bund
                        orderRef = GetNodeValue(XMLPart, xPathListLine, xPathInvOrderRef, i);
#endif
                        Einheit = GetNodeValue(XMLPart, xPathListLine, xPathUnit, i);
                        var myRow = (DsInvoice.TblInvDetailsRow)myDs.TblInvDetails.Rows.Add();
                        myRow.SpMenge = Menge;
                        myRow.SpArtikelNr = ArtikelNr;
                        myRow.SpBezeichnung = Beschreibung;
                        myRow.SpEinzelpreis = stueckpreis;
                        myRow.SpEinheit = Einheit;
                        myRow.SpRabattProz = RabattProz;
                        myRow.SpMwSt = Mwst;
#if ebInterface4Bund
                        myRow.SpBestellBezug = orderRef;
#endif
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return false;
            }

            return true;
        }

        public virtual void SaveDocumentAsPDF(ref Document document, string targetPath)
        {

            WdExportFormat exportFormat = WdExportFormat.wdExportFormatPDF;
            bool openAfterExport = false;
            WdExportOptimizeFor exportOptimizeFor = WdExportOptimizeFor.wdExportOptimizeForPrint;
            WdExportRange exportRange = WdExportRange.wdExportAllDocument;
            int startPage = 1;
            int endPage = document.ComputeStatistics(WdStatistic.wdStatisticPages) - 1;
            WdExportItem exportItem = WdExportItem.wdExportDocumentContent;
            bool includeDocProps = false;
            bool keepIRM = true;
            WdExportCreateBookmarks createBookmarks = WdExportCreateBookmarks.wdExportCreateWordBookmarks;
            bool docStructureTags = true;
            bool bitmapMissingFonts = true;
            bool useISO19005_1 = false;
            object missing = Missing.Value;

            if (document != null)
                document.ExportAsFixedFormat(
                    targetPath,
                    exportFormat,
                    openAfterExport,
                    exportOptimizeFor,
                    exportRange,
                    startPage,
                    endPage,
                    exportItem,
                    includeDocProps,
                    keepIRM,
                    createBookmarks,
                    docStructureTags,
                    bitmapMissingFonts,
                    useISO19005_1,
                    ref missing);


            //Process p = new Process();
            //p.StartInfo.FileName = targetPath;
            //p.Start();
        }

    }
    public static class DocumentExtensions
    {
        public static XmlDocument ToXmlDocument(this XDocument xDocument)
        {
            var xmlDocument = new XmlDocument();
            using (var xmlReader = xDocument.CreateReader())
            {
                xmlDocument.Load(xmlReader);
            }
            return xmlDocument;
        }

        public static XDocument ToXDocument(this XmlDocument xmlDocument)
        {
            using (var nodeReader = new XmlNodeReader(xmlDocument))
            {
                nodeReader.MoveToContent();
                return XDocument.Load(nodeReader);
            }
        }
    }


}